﻿using IM.Easy.Core.AppContext;
using IM.Easy.Core.Security;
using IPTools.Core;
using Microsoft.AspNetCore.Http;
using NetTaste;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UAParser;
using Parser = UAParser.Parser;

namespace IM.Easy.Core.Extensions
{
    public static class HttpContextExtensions
    {
        /// <summary>
        /// 获取客户端IP信息
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static IpInfo GetRemoteIpInfo(this HttpContext context)
        {
            var clientIp = context.GetClientUserIp();
            var remoteInfo = IpTool.Search(clientIp);
            return remoteInfo;
        }
        /// <summary>
        /// 获取浏览器信息
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static ClientInfo GetClientInfo(this HttpContext context)
        {
            var ua = context.GetUserAgent();
            var uaParser = Parser.GetDefault();
            ClientInfo c = uaParser.Parse(ua);

            return c;
        }

        /// <summary>
        /// 获取代理信息
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetUserAgent(this HttpContext context)
        {
            return context.Request.Headers["User-Agent"];
        }

        /// <summary>
        /// 获取客户端IP
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetClientUserIp(this HttpContext context)
        {
            if (context == null) return "";
            var result = context.Request.Headers["X-Forwarded-For"];
            if (string.IsNullOrEmpty(result))
            {
                result = context.Connection.RemoteIpAddress?.MapToIPv4()?.ToString();
            }
            //string json = JsonConvert.SerializeObject(context.Request.Headers);
            //Console.WriteLine("请求头数据：{0}", json);
            if (string.IsNullOrEmpty(result))
                throw new Exception("获取IP失败");
            //var ipV4 = context.Connection.RemoteIpAddress.MapToIPv4();
            //result = ipV4.ToString();
            return result;
        }

        /// <summary>
        /// 获取请求体信息
        /// </summary>
        /// <returns></returns>
        public static async Task<string> GetRequestBody(this HttpContext context)
        {
            var body = string.Empty;
            // 读取并缓存 RequestBody
            context.Request.EnableBuffering(); // 允许多次读取请求体
            using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, leaveOpen: true))
            {
                body = await reader.ReadToEndAsync(); // 读取请求体
            }
            // 将请求体流的指针复位，以便后续中间件可以再次读取
            context.Request.Body.Position = 0;
            return body;
        }

        /// <summary>
        /// 获取返回体信息
        /// </summary>
        /// <returns></returns>
        public static async Task<string> GetResponseBody(this HttpContext context)
        {
            var body = string.Empty;
            // 拦截 ResponseBody
            var originalResponseBodyStream = context.Response.Body; // 保存原始响应流
            using (var memoryStream = new MemoryStream())
            {
                context.Response.Body = memoryStream; // 将响应重定向到 memoryStream


                // 读取 ResponseBody
                memoryStream.Position = 0; // 重置内存流的指针
                body = await new StreamReader(memoryStream).ReadToEndAsync(); // 读取响应体

                // 将内存流中的响应体写回到原始响应流
                memoryStream.Position = 0;
                await memoryStream.CopyToAsync(originalResponseBodyStream); // 写回到原始响应流
            }
            return body;
        }

        /// <summary>
        /// 获取当前连接ID
        /// </summary>
        /// <returns></returns>
        public static string GetClientId(this HttpContext context, int length = 12)
        {
            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
            var random = new Random();
            var result = new char[length];

            for (int i = 0; i < length; i++)
            {
                result[i] = chars[random.Next(chars.Length)];
            }

            return new string(result);
        }
    }
}
